#include <QtOpenGL>
#include <math.h>
#include <iostream>
#include <gl/gl.h>
#include <gl/GLU.h>

#include "glwidget.h"
#include "TriMesh.h"

GLWidget::GLWidget(QWidget *parent)
: QGLWidget( parent)
{
	//setFormat(QGLFormat(QGL::DoubleBuffer | QGL::DepthBuffer));
	m_pModel = NULL;
	m_bLeftDown = FALSE;
	m_nWinWidth = size().width();
	m_nWinHeight = size().height();
	m_pEyePosition= QVector3D(0.0f, 0.0f, 0.0f);
}

GLWidget::~GLWidget()
{
//	
//	delete m_pArcBall;
//	delete m_pEyePosition;
//	//QGLWidget::~QGLWidget();
}

void GLWidget::resizeEvent(QResizeEvent* event)
{
	m_nWinWidth = event->size().width();
	m_nWinHeight = event->size().height();
	resizeGL(m_nWinWidth,m_nWinHeight);
}


void GLWidget::setEye(QVector3D& pos, QVector3D& desti, QVector3D& up )
{
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(pos.x(), pos.y(), pos.z(), desti.x(), desti.y(), desti.z(), up.x(), up.y(), up.z());
}

void GLWidget::resizeGL(int width, int height)
{
	glViewport(0, 0, width, height);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	GLfloat x = GLfloat(width) / height;
	//glFrustum(-x, +x, -1.0, +1.0, 4.0, 15.0);
	gluPerspective(60.0, x, 0.5, 20.0);
	glMatrixMode(GL_MODELVIEW);
}

void GLWidget::setupLight()
{
	// Ambient light
	QVector3D* AmbientLight = new QVector3D(0.1f, 0.1f, 0.1f);

	// Total 2 lights
	Light*  DefaultLight = new Light[2];
	DefaultLight[0].position[0] = -5.f; DefaultLight[0].position[1] = 0.f;
	DefaultLight[0].position[2] = 10.f;
	DefaultLight[0].color[0] = 1.0f; DefaultLight[0].color[1] = 1.0f;
	DefaultLight[0].color[2] = 1.0f;
	DefaultLight[1].position[0] = 0.0f; DefaultLight[1].position[1] = 5.0f;
	DefaultLight[1].position[2] = -2.0f;
	DefaultLight[1].color[0] = 1.0f; DefaultLight[1].color[1] = 1.0f;
	DefaultLight[1].color[2] = 1.0f;

	float m[4]={AmbientLight->x(), AmbientLight->y(), AmbientLight->z(), 1.0};
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, m);

	glLightfv(GL_LIGHT0, GL_POSITION, DefaultLight[0].position);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, DefaultLight[0].color);
	glLightfv(GL_LIGHT0, GL_SPECULAR, DefaultLight[0].color);

	glLightfv(GL_LIGHT1, GL_POSITION, DefaultLight[1].position);
	glLightfv(GL_LIGHT1, GL_DIFFUSE, DefaultLight[1].color);
	glLightfv(GL_LIGHT1, GL_SPECULAR, DefaultLight[1].color);

	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	glEnable(GL_LIGHT1);


	delete AmbientLight;
	delete[] DefaultLight;

}

void GLWidget::initializeGL()
{
	glClearColor(.82f, .82f, .82f, 1.0f);   
	//setBackground();


	//m_pArcBall = new CArcBall;
	 m_pArcBall.InitBall();

	m_pEyePosition = QVector3D(0.0f, 0.0f, 3.5f);
	setEye(m_pEyePosition);

	setupLight();

	glShadeModel(GL_SMOOTH);
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);
	glEnable(GL_CULL_FACE);

}

void GLWidget::paintGL()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	draw();
}

void GLWidget::mousePressEvent(QMouseEvent *event)
{
	QPoint point = event->pos();

	if(event->buttons() & Qt::LeftButton)
	{
		m_bLeftDown = TRUE;
		m_pArcBall.MouseDown(point,m_nWinWidth,m_nWinHeight);
		updateGL();
	}
	
}

void GLWidget::mouseMoveEvent(QMouseEvent *event)
{
	QPoint point = event->pos();

	if (event->buttons() & Qt::LeftButton) {
		m_pArcBall.MouseMove(point,m_nWinWidth,m_nWinHeight);
		updateGL();
	} 
	
}

void GLWidget::mouseReleaseEvent(QMouseEvent * event)
{
	QPoint point = event->pos();

	if(m_bLeftDown)
	{
		m_bLeftDown = FALSE;
		m_pArcBall.MouseUp(point,m_nWinWidth,m_nWinHeight);
		updateGL();
	}
}

void GLWidget::wheelEvent(QWheelEvent *event)
{
//	if (m_pEyePosition)
	{
		double numDegrees = -event->delta() / 8.0;
		double numSteps = numDegrees / 60.0;

		qreal z = m_pEyePosition.z();
		m_pEyePosition.setZ(z + numSteps);

		setEye(m_pEyePosition);

		updateGL();
	}
	
}


void GLWidget::draw()
{	
	if( NULL != m_pModel )
	{
		glMatrixMode(GL_MODELVIEW);
		glPushMatrix();
		glMultMatrixf(m_pArcBall.GetBallMatrix());


			m_pModel->DrawScene();

		glPopMatrix();
		glFlush();
	}

}


void GLWidget::setModel(TriMesh *m)
{
	m_pModel = m;
}

//void GLWidget::setBackground()
//{
//	gradient.setCoordinateMode(QGradient::ObjectBoundingMode);
//	gradient.setCenter(0.45,0.50);
//	gradient.setFocalPoint(0.40, 0.45);
//	gradient.setColorAt(0.0, QColor(105,146,182));
//	gradient.setColorAt(0.4, QColor(81,113,150));
//	gradient.setColorAt(0.8, QColor(16,56,121));
//
//	QPainter painter(this);
//	painter.setPen(Qt::NoPen);
//	painter.setBrush(gradient);
//}
//
//
//void GLWidget::paintEvent(QPaintEvent *event)
//{
//	setBackground();
//	SwapBuffers();
//}
//
